//
// Saru.Base.Math.colorrgb.cs: 3 component color operations
//
// Author:
//   Jan Van Sweevelt (vansweej@gmail.com)
//
// Copyright (C) 2007
// 

using System;

namespace Saru.Base.Math {

    public class ColorRGB {

// Constructors
	public ColorRGB() {
	    tuple = new float[3];
	}

	public ColorRGB(float R, float G, float B) {
	    tuple = new float[3];

	    tuple[0] = R;
	    tuple[1] = G;
	    tuple[2] = B;
	}

	public ColorRGB(float[] C) {
	    tuple = C;
	}

	public ColorRGB(ColorRGB C) {
	    tuple = C.tuple;
	}

// member access
	public float[] RGB {
	    get {
		return tuple;
	    }

	    set {
		tuple = value;
	    }
	}

	public float R {
	    get {
		return tuple[0];
	    }

	    set {
		tuple[0] = value;
	    }
	}

	public float G {
	    get {
		return tuple[1];
	    }

	    set {
		tuple[1] = value;
	    }
	}

	public float B {
	    get {
		return tuple[2];
	    }

	    set {
		tuple[2] = value;
	    }
	}

//comparison
	public static bool operator==(ColorRGB C1, ColorRGB C2) {
	    return C1.tuple == C2.tuple;
	}

	public static bool operator!=(ColorRGB C1, ColorRGB C2) {
	    return C1.tuple != C2.tuple;
	}

	public static bool operator<(ColorRGB C1, ColorRGB C2) {
	    return (C1.tuple[0] < C2.tuple[0] && 
		    C1.tuple[1] < C2.tuple[1] &&
		    C1.tuple[2] < C2.tuple[2]);
	}

        public static bool operator>(ColorRGB C1, ColorRGB C2) {
	    return (C1.tuple[0] > C2.tuple[0] && 
		    C1.tuple[1] > C2.tuple[1] &&
		    C1.tuple[2] > C2.tuple[2]);
	}

	public static bool operator<=(ColorRGB C1, ColorRGB C2) {
	    return (C1.tuple[0] <= C2.tuple[0] && 
		    C1.tuple[1] <= C2.tuple[1] &&
		    C1.tuple[2] <= C2.tuple[2]);
	}

        public static bool operator>=(ColorRGB C1, ColorRGB C2) {
	    return (C1.tuple[0] >= C2.tuple[0] && 
		    C1.tuple[1] >= C2.tuple[1] &&
		    C1.tuple[2] >= C2.tuple[2]);
	}

	public override bool Equals(object value) {
	    if(value == null) return false;
	    if (GetType() == value.GetType()) return this == (ColorRGB)value;
	    
	    return false;
	}

	public override int GetHashCode() {
	    return tuple.GetHashCode();
	}

// operators
	public static ColorRGB operator+ (ColorRGB C1, ColorRGB C2) {
	    return new ColorRGB(C1.tuple[0] + C2.tuple[0], 
				C1.tuple[1] + C2.tuple[1],
				C1.tuple[2] + C2.tuple[2]); 
	}

	public static ColorRGB operator- (ColorRGB C1, ColorRGB C2) {
	    return new ColorRGB(C1.tuple[0] - C2.tuple[0], 
				C1.tuple[1] - C2.tuple[1],
				C1.tuple[2] - C2.tuple[2]); 
	}

	public static ColorRGB operator* (ColorRGB C1, ColorRGB C2) {

	    return new ColorRGB(C1.tuple[0] * C2.tuple[0], C1.tuple[1] * C2.tuple[1], C1.tuple[2] * C2.tuple[2]); 
	}

	public static ColorRGB operator* (ColorRGB C1, Single Scalar) {

	    return new ColorRGB(C1.tuple[0] * Scalar, C1.tuple[1] * Scalar, C1.tuple[2] * Scalar); 
	}

	public void Clamp() {
	    for (int i = 0; i < 3; i++)
	    {
		if (tuple[i] > 1.0f)
		{
		    tuple[i] = 1.0f;
		}
		else if (tuple[i] < 0.0f)
		{
		    tuple[i] = 0.0f;
		}
	    }
	}

	public void ScaleByMax() {
	    float max = tuple[0];
	    if (tuple[1] > max)
	    {
		max = tuple[1];
	    }
	    if (tuple[2] > max)
	    {
		max = tuple[2];
	    }
	    
	    if (max > 1.0f)
	    {
		float invmax = 1.0f/max;
		for (int i = 0; i < 3; i++)
		{
		    tuple[i] *= invmax;
		}
	    }
	}

	private float[] tuple;
    }

}
